package com.csp.app.common;

import com.alibaba.fastjson.JSONObject;
import com.csp.app.service.RedisService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

@Component
@ServerEndpoint("/websocket/{id}")
public class ChatServer {
    private final static Logger logger = LoggerFactory.getLogger(ChatServer.class);
    private static ConcurrentHashMap<Long, Session> sessionMap = new ConcurrentHashMap<>();
    public static RedisService redisService;

    /**
     * 用户接入
     *
     * @param session 可选
     */
    @OnOpen
    public void onOpen(Session session, @PathParam("id") Long id) {
        sessionMap.put(id, session);
        logger.info("id:{}连接", id);
        logger.info("当前在线人数:{}", sessionMap.size());
        String key = String.format(Const.OFFLINE_MSG_TEMPLATE, id);
        Long ttl = redisService.ttl(key, Const.DEFAULT_INDEX);
        if (ttl != null && ttl != -2) {
            List<JSONObject> jsonObjects = redisService.lpopObjects(key, JSONObject.class);
            for (JSONObject jsonObject : jsonObjects) {
                try {
                    session.getBasicRemote().sendText(jsonObject.toJSONString());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        /*key = String.format(Const.OFFLINE_ADD_FRIEND, id);
        List<JSONObject> addFriendMsgs = redisService.lpopObjects(key, JSONObject.class);
        if (CollectionUtils.isNotEmpty(addFriendMsgs)) {
            JSONObject addFriendRequest = new JSONObject();
            addFriendRequest.put("emit","addRequest");
            addFriendRequest.put("requests",addFriendMsgs);
            try {
                session.getBasicRemote().sendText(addFriendRequest.toString());
            } catch (IOException e) {
                e.printStackTrace();
            }
        }*/
    }

    /**
     * 接收到来自用户的消息
     *
     * @param message
     * @param session
     */
    @OnMessage
    public void onMessage(String message, Session session) {
        //把用户发来的消息解析为JSON对象
        JSONObject obj = JSONObject.parseObject(message);
        JSONObject data = obj.getJSONObject("data");
        JSONObject to = data.getJSONObject("to");
        JSONObject mine = data.getJSONObject("mine");
        Long id = to.getLong("id");
        long mineId = mine.getLongValue("id");
        Long fromid = to.getLong("fromid");
        /*if (mineId == id) {
            long tempId = id;
            id = fromid;
            fromid = tempId;
        }*/
        Session toSession = sessionMap.get(id);

        JSONObject personalMsg = new JSONObject();
        personalMsg.put("id", id);
        personalMsg.put("avatar", mine.getString("avatar"));
        personalMsg.put("type", "friend");
        personalMsg.put("mine", false);
        personalMsg.put("content", mine.get("content"));
        personalMsg.put("fromid", mineId);
        personalMsg.put("username", mine.get("username"));
        personalMsg.put("timestamp", System.currentTimeMillis());
        personalMsg.put("emit", "chatMessage");
        personalMsg.put("temporary", false);
        Object toId = to.get("id");
        if (toSession != null) {

            toSession.getAsyncRemote().sendText(personalMsg.toJSONString());
            logger.info("{} say '{}' to {}", fromid, mine.get("content"), toId);
//            logger.info("{} say '{}' to {}", mine.get("username"), mine.get("content"), to.get("username"));
        } else {
            JSONObject sysMsg = new JSONObject();
            sysMsg.put("system", true);
            sysMsg.put("id", id);
            sysMsg.put("type", "friend");
            sysMsg.put("content", "对方不在线");
            sysMsg.put("emit", "chatMessage");
            session.getAsyncRemote().sendText(sysMsg.toJSONString());
            String key = String.format(Const.OFFLINE_MSG_TEMPLATE, toId);
            redisService.rpushObject(key, personalMsg);

        }
    }

    /**
     * 用户断开
     *
     * @param session
     */
    @OnClose
    public void onClose(Session session, @PathParam("id") Long id) {
        sessionMap.remove(id);
        logger.info("id:{}离线", id);
        logger.info("当前在线人数:{}", sessionMap.size());
    }

    /**
     * 用户连接异常
     *
     * @param t
     */
    @OnError
    public void onError(Throwable t) {
        try {
            throw t;
        } catch (Throwable throwable) {
            logger.error("error:{}", throwable);
        }
    }

    public Session getSessionById(Long id) {
        return sessionMap.get(id);
    }

    public Map<Long, Session> getsSessionMap() {
        return sessionMap;
    }
}